package ac.man.cs.afzal.tcm.nlp;


import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.LinkedList;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.Properties;

/**
 * XML_Tree_Generator class converts the Phrase-Structured Parsed files (output of Stanford NLP into XML
 * <p>Company: The University of Manchester</p>
 *
 * @author Hammad Afzal
 * @version 1.0
 * Last Modification Date: 16 Jan, 2013
 *
 */
public class XML_Tree_Generator
{

    private String MODE = "MODE";

    private String PARSED_SENTENCES_PENN_CORPUS = "PARSED_SENTENCES_PENN_CORPUS";
    private String PARSED_SENTENCES_PENN_TRAINING = "PARSED_SENTENCES_PENN_TRAINING";
    
    private String PARSED_SENTENCES_XML_CORPUS = "PARSED_SENTENCES_XML_CORPUS";
    private String PARSED_SENTENCES_XML_TRAINING = "PARSED_SENTENCES_XML_TRAINING";

    public final static String xmlDeclaration = "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>";
    public final static String xmlSchema = "<corpus-info xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"corpus.xsd\">";

    private static String[] STOP_PATTERNS = {"/[*.*/]", "\\r","\\n", "","<st_,>,</st_,>","<st_.>.</st_.>",
    "<st_''>''</st_''>","<st_CC>&</st_CC>", "<st_ROOT>", "</st_ROOT>"};

    File_Manager_Impl fileManager = new File_Manager_Impl();
    String_Manipulator_Impl strMan = new String_Manipulator_Impl();

    public XML_Tree_Generator()
    {
        try
        {
            Properties props  = new Properties();
            props.load(new FileInputStream("Term_Classification.properties"));

            PARSED_SENTENCES_XML_CORPUS = props.getProperty(PARSED_SENTENCES_XML_CORPUS);
            PARSED_SENTENCES_XML_TRAINING = props.getProperty(PARSED_SENTENCES_XML_TRAINING);
            PARSED_SENTENCES_PENN_CORPUS = props.getProperty(PARSED_SENTENCES_PENN_CORPUS);
            PARSED_SENTENCES_PENN_TRAINING = props.getProperty(PARSED_SENTENCES_PENN_TRAINING);

            MODE = props.getProperty(MODE);
        }

        catch (FileNotFoundException ex)
        {
            Logger.getLogger(XML_Tree_Generator.class.getName()).log(Level.SEVERE, null, ex);
        }        catch (IOException ex)
        {
            Logger.getLogger(XML_Tree_Generator.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * Converts brackets in PennTreeFormat to XML Tags
     */
    public void convert_penn_to_xml()
    {
        File penn_sentences_dir = MODE.equals("Corpus") ? new File(PARSED_SENTENCES_PENN_CORPUS) : new File(PARSED_SENTENCES_PENN_TRAINING);
        for (String dir_name : penn_sentences_dir.list())
        {
            File mkdir = MODE.equals("Corpus") ? new File(PARSED_SENTENCES_XML_CORPUS + "//" + dir_name) : new File(PARSED_SENTENCES_XML_TRAINING + "//" + dir_name);
            mkdir.mkdir();

            File file_doc = MODE.equals("Corpus") ? new File(PARSED_SENTENCES_PENN_CORPUS + "//" + dir_name) : new File(PARSED_SENTENCES_PENN_TRAINING + "//" + dir_name);
            for (String file_name : file_doc.list())
            {
                StringBuffer file_contents_buffer = new StringBuffer();

                file_contents_buffer = (MODE.equals("Corpus")) ? fileManager.fileReader(PARSED_SENTENCES_PENN_CORPUS
                        + "//" + dir_name + "//" + file_name) : fileManager.fileReader(PARSED_SENTENCES_PENN_TRAINING
                        + "//" + dir_name + "//" + file_name);

                String output_file_name = fileManager.strip_file_name_from_file_name_plus_extension(file_name, "txt");
                output_file_name = output_file_name + ".xml";

                String output_path = MODE.equals("Corpus") ? PARSED_SENTENCES_XML_CORPUS + "//" + dir_name + "//" + output_file_name
                        : PARSED_SENTENCES_XML_TRAINING + "//" + dir_name + "//" + output_file_name;

                String file_contents = brackets_to_tags(file_contents_buffer.toString());
                fileManager.fileWriter(file_contents, output_path);
                file_contents = "";
            }
        }
    }

    private String brackets_to_tags(String contents)
    {
        int count = 0;
        StringBuilder xmlWritor = new StringBuilder();
        LinkedList element = new LinkedList();

        xmlWritor.append(xmlDeclaration);
        xmlWritor.append(System.getProperty("line.separator"));
        xmlWritor.append(xmlSchema);
        xmlWritor.append(System.getProperty("line.separator"));

        StringTokenizer st1 = new StringTokenizer(contents.toString(), " ");

        while (st1.hasMoreElements())
        {
            String term = st1.nextToken();
            if (term.startsWith("("))
            {
                xmlWritor.append("<st_" + term.substring(1, term.length()) + ">");
                element.add(term.substring(1, term.length()));
                count++;
            } 
            else if (term.contains(")"))
            {
                int index = term.indexOf(")");
                int length = term.substring(index, term.lastIndexOf(")")).length();
                xmlWritor.append(term.substring(0, index));

                int j = length + 1;
                try
                {
                    while (j > 0)
                    {
                        xmlWritor.append("</st_" + element.getLast().toString() + ">");
                        xmlWritor.append(System.getProperty("line.separator"));
                        element.removeLast();
                        j--;
                    }
                } 
                catch (Exception ex)
                {
                    System.out.println("Exception while converting brackets into tags" + ex.getMessage());
                }
            }
        }
        xmlWritor.append("</corpus-info>");
        xmlWritor.append(System.getProperty("line.separator"));
        String file_contents = xmlWritor.toString();

        for (int i = 0; i < STOP_PATTERNS.length; i++)
        {
            file_contents = strMan.pattern_replacer(file_contents, STOP_PATTERNS[i], "");
        }
        return file_contents.toString();

    }
}
